package org.lds.message.center.email;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.lds.message.center.common.AbstractMessageService;
import org.lds.message.center.common.MessageHandler;
import org.lds.message.center.common.model.request.EmailRequest;
import org.lds.message.center.common.model.response.GetTemplateAdminResponse;
import org.lds.message.center.common.util.AssertUtil;
import org.lds.message.center.common.util.PropertiesUtil;
import org.lds.message.center.email.constant.EmailConstant;
import org.lds.message.center.email.enums.EmailErrorEnum;
import org.lds.message.center.email.properties.EmailProperties;
import org.lds.message.center.plugin.core.kafka.KafkaProducer;
import org.lds.message.center.plugin.core.remote.RemoteService;
import org.springframework.util.PropertyPlaceholderHelper;

import java.util.List;
import java.util.Objects;
import java.util.Properties;

public class EmailMessageService extends AbstractMessageService<EmailRequest> {
    private final PropertyPlaceholderHelper placeholder = new PropertyPlaceholderHelper("${", "}", ":", true);
    private final EmailProperties emailProperties;
    private final KafkaProducer kafkaProducer;
    private final RemoteService remoteService;

    public EmailMessageService(MessageHandler<EmailRequest> messageHandler, EmailProperties emailProperties, KafkaProducer kafkaProducer, RemoteService remoteService) {
        super(messageHandler);
        this.emailProperties = emailProperties;
        this.kafkaProducer = kafkaProducer;
        this.remoteService = remoteService;
    }

    @Override
    public String channelName() {
        return EmailConstant.CHANNEL_NAME;
    }

    @Override
    public String channelType() {
        return EmailConstant.CHANNEL_TYPE;
    }

    @Override
    public Class<EmailRequest> supportClass() {
        return EmailRequest.class;
    }

    @Override
    public void check(EmailRequest request) {
        AssertUtil.assertTrue(emailProperties.isEnabled(), EmailErrorEnum.PLUGIN_CLOSED);
        AssertUtil.assertTrue(Objects.nonNull(request), EmailErrorEnum.REQUEST_INVALID);

        AssertUtil.assertTrue(ArrayUtils.isNotEmpty(request.getTo()), EmailErrorEnum.TO_INVALID);
        for (String to : request.getTo()) {
            AssertUtil.assertTrue(StringUtils.isNotEmpty(to), EmailErrorEnum.TO_INVALID);
        }
        if (ArrayUtils.isNotEmpty(request.getCc())) {
            for (String cc : request.getCc()) {
                AssertUtil.assertTrue(StringUtils.isNotEmpty(cc), EmailErrorEnum.CC_INVALID);
            }
        }
        if (ArrayUtils.isNotEmpty(request.getBcc())) {
            for (String bcc : request.getBcc()) {
                AssertUtil.assertTrue(StringUtils.isNotEmpty(bcc), EmailErrorEnum.BCC_INVALID);
            }
        }


        List<EmailRequest.Attachment> attachments = request.getAttachments();
        if (request.isMultipart()) {
            AssertUtil.assertTrue(CollectionUtils.isNotEmpty(attachments), EmailErrorEnum.ATTACHMENTS_INVALID);
            for (EmailRequest.Attachment attachment : attachments) {
                AssertUtil.assertTrue(StringUtils.isNotEmpty(attachment.getFilename()), EmailErrorEnum.FILE_NAME_INVALID);
                AssertUtil.assertTrue(StringUtils.isNotEmpty(attachment.getFileAddress()), EmailErrorEnum.FILE_ADDRESS_INVALID);
            }
        } else {
            AssertUtil.assertTrue(CollectionUtils.isEmpty(attachments), EmailErrorEnum.ATTACHMENTS_INVALID);
        }

        if (StringUtils.isEmpty(request.getSubject()) && StringUtils.isEmpty(request.getText())) {
            // 从模板中获取主题和内容
            GetTemplateAdminResponse template = remoteService.getTemplate(request.getAppName(), request.getTemplateName());
            request.setSubject(template.getSubject());
            request.setText(template.getText());

            Properties properties = PropertiesUtil.getProperties(request.getTemplateParam());
            if (Objects.nonNull(properties)) {
                request.setText(placeholder.replacePlaceholders(template.getText(), properties));
            }
        }
        AssertUtil.assertTrue(StringUtils.isNotEmpty(request.getSubject()), EmailErrorEnum.SUBJECT_INVALID);
        AssertUtil.assertTrue(StringUtils.isNotEmpty(request.getText()), EmailErrorEnum.TEXT_INVALID);
    }

    @Override
    protected void store(EmailRequest request) {
        kafkaProducer.send(emailProperties.getTopic(), request);
    }

}
